package org.dromara.hm.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.service.CustomerService;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.*;
import org.dromara.hm.domain.bo.HmSaleOrderRefundBo;
import org.dromara.hm.domain.vo.*;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderPickUpVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderRefundVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderVo;
import org.dromara.hm.mapper.*;
import org.dromara.hm.mapper.saleOrder.HmSaleOrderMapper;
import org.dromara.hm.mapper.saleOrder.HmSaleOrderPickUpMapper;
import org.dromara.hm.service.IHmSaleOrderPickUpService;
import org.dromara.hm.service.IHmTodoItemsService;
import org.dromara.hm.service.IStatisticsService;
import org.dromara.system.domain.SysDept;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.mapper.SysUserRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class StatisticsServiceImpl implements IStatisticsService {
    private final HmSaleOrderMapper baseMapper;
    private final HmProductMapper productMapper;
    private final HmCustomerMapper customerMapper;
    private final HmTodoItemsMapper todoItemsMapper;
    private final SysDeptMapper sysDeptMapper;
    private final HmStockMapper stockMapper;
    private final HmSaleOrderPickUpMapper saleOrderPickUpMapper;
    private final HmSaleOrderMapper saleOrderMapper;

    private final IHmSaleOrderPickUpService hmSaleOrderPickUpService;

    private final IHmTodoItemsService todoItemsService;

    private final CustomerService customerService;
    private final StatisticsMapper statisticsMapper;

    @Autowired
    private HmThresholdManagementMapper hmThresholdManagementMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Override
    public Map<String, Long> queryCustomerActivity() {
        Map<String, Long> activityResult = new HashMap<>();
        // 查询总客户数量
        QueryWrapper<HmCustomer> totalWrapper = Wrappers.<HmCustomer>query()
            .isNotNull("customer_activity") // 客户活跃度
            .eq("del_flag", 0); // del_flag为0表示未删除
        Long totalCount = customerMapper.selectCount(totalWrapper);
        activityResult.put("total", totalCount);
        // 定义活跃度分类及对应的中文描述
        String[] activityCodes = {"1", "2", "3", "4"};
        // 按分类查询客户数量
        for (int i = 0; i < activityCodes.length; i++) {
            QueryWrapper<HmCustomer> wrapper = Wrappers.query();
            wrapper.eq("customer_activity", activityCodes[i]);
            Long count = customerMapper.selectCount(wrapper);
            activityResult.put("num"+(i+1), count);
        }

        return activityResult;
    }

    @Override
    public Map<String, Object> queryProductActivity(Long productId) {
        Map<String, Object> activityResult = new HashMap<>();
        //店铺数量
        QueryWrapper<SysDept> wrapperShop = Wrappers.query();
        wrapperShop.eq("dept_category", "DP");
        Long shopNum = sysDeptMapper.selectCount(wrapperShop);
        activityResult.put("shopNum", shopNum);
        //库存数量
        Long productDept=0L;
        if (!LoginHelper.isAdmin() && !LoginHelper.isDeptManager() && !LoginHelper.isChiefFinancial()) {
            productDept = LoginHelper.getDeptId();
        }
        int stockNum=statisticsMapper.selectStockNum(productId,productDept);
        activityResult.put("stockNum", stockNum);
        //当月提货数量
        QueryWrapper<HmSaleOrderPickUp> wrapperPick = Wrappers.query();
        wrapperPick.select( "IFNULL(SUM(pick_up_num),0) as pickUpNum");
        if(null != productId){
            wrapperPick.eq("sale_product_id", productId);
        }
        if (!LoginHelper.isAdmin() && !LoginHelper.isDeptManager() && !LoginHelper.isChiefFinancial()) {
            wrapperPick.eq("create_by", LoginHelper.getUserId());
        }
        LocalDate targetLocalDate = LocalDate.now();
        String formattedDate = targetLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
        wrapperPick.apply("DATE_FORMAT(pick_up_time, '%Y-%m') = {0}", formattedDate);
        wrapperPick.like("product_type", "CP");
        wrapperPick.eq("pick_up_type", "1");
        List<HmSaleOrderPickUp> hmSaleOrderPickUps = saleOrderPickUpMapper.selectList(wrapperPick);
        activityResult.put("pickNum", hmSaleOrderPickUps.get(0).getPickUpNum());
        return activityResult;
    }



    @Override
    public Map<String, Object> querySaleNumOrMoney(String type,String date) {
        Map<String, Object> activityResult = new HashMap<>();
        Long userId=0L;
        // 当前登录角色为管理层以及财务总监和市场总监时查询所有数据
        if (!LoginHelper.isAdmin() && !LoginHelper.isDeptManager() && !LoginHelper.isChiefFinancial()) {
            userId = LoginHelper.getUserId();
        }
        BigDecimal totalAmount  = statisticsMapper.querySaleOrderCount(date,userId);
        BigDecimal returnSaleAmount  = statisticsMapper.querySaleReturnCount(date,userId);
        activityResult.put("totalSaleAmount",totalAmount);
        activityResult.put("returnSaleAmount", returnSaleAmount);
        activityResult.put("noReturnSaleAmount", totalAmount.subtract(returnSaleAmount));

        QueryWrapper<HmProduct> queryWrappers =  new QueryWrapper<>();
        queryWrappers.like("product_type", "CP");
        List<HmProductVo> hmProductVos = productMapper.selectVoList(queryWrappers);
        if("num".equals(type)){
            //销售数量
            QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
            if(date.length()<5){//年
                queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
            }else {
                queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
            }
            queryWrapper.select( "sale_product_id saleProductId", "IFNULL(SUM(sale_num),0) as saleNum")
                .groupBy("sale_product_id")
                .orderByDesc("saleNum");
            List<HmSaleOrderVo> maps = saleOrderMapper.selectVoList(queryWrapper);
            Set<Long> productIds = new HashSet<>();
            for (HmSaleOrderVo hmSaleOrderVo : maps) {
                productIds.add(hmSaleOrderVo.getSaleProductId());
            }
            for (HmProductVo productVo : hmProductVos) {
                if (!productIds.contains(productVo.getProductId())) {
                    // 这里假设你可以将 HmProductVo 转换为 HmSaleOrderVo
                    HmSaleOrderVo saleOrderVo = new HmSaleOrderVo();
                    saleOrderVo.setSaleProductId(productVo.getProductId());
                    saleOrderVo.setSaleNum(BigDecimal.valueOf(0));
                    maps.add(saleOrderVo);
                }
            }
            activityResult.put("list", maps);
        }
        if("money".equals(type)){
            //销售金额
            QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
            if(date.length()<5){//年
                queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
            }else {
                queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
            }
            queryWrapper.select( "sale_product_id saleProductId", "IFNULL(SUM(sale_amount),0) as saleAmount")
                .groupBy("sale_product_id")
                .orderByDesc("saleAmount");
            List<HmSaleOrderVo> maps = saleOrderMapper.selectVoList(queryWrapper);
            Set<Long> productIds = new HashSet<>();
            for (HmSaleOrderVo hmSaleOrderVo : maps) {
                productIds.add(hmSaleOrderVo.getSaleProductId());
            }
            for (HmProductVo productVo : hmProductVos) {
                if (!productIds.contains(productVo.getProductId())) {
                    // 这里假设你可以将 HmProductVo 转换为 HmSaleOrderVo
                    HmSaleOrderVo saleOrderVo = new HmSaleOrderVo();
                    saleOrderVo.setSaleProductId(productVo.getProductId());
                    saleOrderVo.setSaleAmount(BigDecimal.valueOf(0));
                    maps.add(saleOrderVo);
                }
            }
            activityResult.put("list", maps);
        }
        return  activityResult;
    }
    @Override
    public TableDataInfo<HmStockVo> queryStockDetail(Long productId) {
        List<HmStockVo> list = statisticsMapper.queryStockDetail(productId);
        return TableDataInfo.build(list);
    }

    @Override
    public TableDataInfo<HmSaleOrderPickUp> queryPickDetail(Long productId) {
        QueryWrapper<HmSaleOrderPickUp> wrapperPick = Wrappers.query();
        if(null != productId){
            wrapperPick.eq("sale_product_id", productId);
        }
        LocalDate targetLocalDate = LocalDate.now();
        String formattedDate = targetLocalDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
        wrapperPick.apply("DATE_FORMAT(pick_up_time, '%Y-%m') = {0}", formattedDate);
        wrapperPick.like("product_type", "CP");
        wrapperPick.eq("pick_up_type", "1");
        wrapperPick.orderByDesc("pick_up_num");
        List<HmSaleOrderPickUp> hmSaleOrderPickUps = saleOrderPickUpMapper.selectList(wrapperPick);
        return TableDataInfo.build(hmSaleOrderPickUps);
    }
    public String getDate(){
                // 获取当前时间
        Date currentDate = new Date();
        // 定义日期格式化对象，格式为 'YYYY-MM'
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        // 将当前时间按照指定格式进行格式化
        String formattedDate = sdf.format(currentDate);
        return formattedDate;
    }

    @Override
    public TableDataInfo<HmSaleOrderVo> queryDeptList(Integer size,String date) {
        QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
        queryWrapper.select( "sale_dept saleDept", "IFNULL(SUM(sale_amount),0) as saleAmount")
            .groupBy("sale_dept")
            .orderByDesc("saleAmount");
        if(null != size){queryWrapper.last("LIMIT "+size);}
        if(date.length()<5){//年
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
        }else {
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
        }
        List<HmSaleOrderVo> hmSaleOrderVoList = DataPermissionHelper.ignore(() -> { return saleOrderMapper.selectVoList(queryWrapper); });
        for (HmSaleOrderVo item : hmSaleOrderVoList) {
            BigDecimal returnAmount = statisticsMapper.selectSaleSort(item.getSaleDept(), date);
            item.setReturnAmount(returnAmount);
        }
        return TableDataInfo.build(hmSaleOrderVoList);
    }
    @Override
    public TableDataInfo<HmSaleOrderVo> queryList1(Long id,String date) {
        QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
        queryWrapper
            .eq("sale_dept", id)
            .orderByAsc("sale_order_time");
        if(date.length()<5){//年
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
        }else {
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
        }
        List<HmSaleOrderVo> hmSaleOrderVoList = DataPermissionHelper.ignore(() -> { return saleOrderMapper.selectVoList(queryWrapper); });
        return TableDataInfo.build(hmSaleOrderVoList);
    }
    @Override
    public TableDataInfo<HmSaleOrderPickUpVo> queryList2(Long id,String date) {
        List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVoList = statisticsMapper.queryList2(id,date,20);
        return TableDataInfo.build(hmSaleOrderPickUpVoList);
    }

    @Override
    public TableDataInfo<HmSaleOrderVo> selectProductSort(Integer size,String date,String productId) {
        List<HmSaleOrderVo> list = statisticsMapper.selectProductSort(size,date,productId);
        return TableDataInfo.build(list);
    }
    @Override
    public TableDataInfo<HmSaleOrderVo> queryList3(Long id,Long productId,String date) {
        QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
        queryWrapper
            .eq("sale_dept", id)
            .eq("sale_product_id", productId)
            .orderByAsc("sale_order_time");
        if(date.length()<5){//年
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
        }else {
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
        }
        List<HmSaleOrderVo> hmSaleOrderVoList = DataPermissionHelper.ignore(() -> { return saleOrderMapper.selectVoList(queryWrapper); });
        return TableDataInfo.build(hmSaleOrderVoList);
    }
    @Override
    public TableDataInfo<HmSaleOrderVo> queryList4(Long id,String date) {
        QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
        queryWrapper
            .eq("sale_user", id)
            .orderByAsc("sale_order_time");
        if(date.length()<5){//年
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
        }else {
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
        }
        List<HmSaleOrderVo> hmSaleOrderVoList = DataPermissionHelper.ignore(() -> { return saleOrderMapper.selectVoList(queryWrapper); });
        return TableDataInfo.build(hmSaleOrderVoList);
    }
    @Override
    public TableDataInfo<HmSaleOrderPickUpVo> queryList5(Long id,String date) {
        List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVoList = statisticsMapper.queryList5(id,date,20);
        return TableDataInfo.build(hmSaleOrderPickUpVoList);
    }



    @Override
    public TableDataInfo<HmSaleOrderVo> selectPersonSort(Integer size,String date) {

        //List<HmSaleOrderVo> list = statisticsMapper.selectPersonSort(size);
        QueryWrapper<HmSaleOrder> queryWrapper = Wrappers.query();
        queryWrapper.select( "sale_user saleUser", "IFNULL(SUM(sale_amount),0) as saleAmount")
            .groupBy("sale_user")
            .orderByDesc("saleAmount");
        if(null != size){queryWrapper.last("LIMIT "+size);}
        if(date.length()<5){//年
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y') = {0}", date);
        }else {
            queryWrapper.apply("DATE_FORMAT(sale_order_time, '%Y-%m') = {0}", date);
        }
        List<HmSaleOrderVo> hmSaleOrderVoList = DataPermissionHelper.ignore(() -> { return saleOrderMapper.selectVoList(queryWrapper); });
        for (HmSaleOrderVo item : hmSaleOrderVoList) {
            item.setReturnAmount(statisticsMapper.selectPersonSort(item.getSaleUser(),date));
        }
        return TableDataInfo.build(hmSaleOrderVoList);
    }

    @Override
    public TableDataInfo<HmSaleOrderVo> selectPersonServerSort(Integer size,String date) {
        List<HmSaleOrderVo> list = statisticsMapper.selectPersonServerSort(size);
        for (HmSaleOrderVo item : list) {
            item.setSaleNum(BigDecimal.valueOf(statisticsMapper.selectSaleNum(item.getSaleUser(),date)));
        }
        return TableDataInfo.build(list);
    }
    @Override
    public TableDataInfo<HmCustomerVo> queryList6(Long id,String date) {
        QueryWrapper<HmCustomer> queryWrapper = Wrappers.query();
        queryWrapper.eq("staff_id", id);
        List<HmCustomerVo> list = DataPermissionHelper.ignore(() -> { return customerMapper.selectVoList(queryWrapper); });
        return TableDataInfo.build(list);
    }

    @Override
    public TableDataInfo<HmTodoItemsVo> queryList7(Long id,String date) {
        List<HmTodoItemsVo> list = statisticsMapper.queryList7(id,date);
        return TableDataInfo.build(list);
    }

    /**
     * 已修改：统一的详情数据获取接口实现
     */
    @Override
    public Map<String, Object> getHomeDataDetail(PageQuery pageQuery, String type, Long id, String date, Long productId) {
        Map<String, Object> result = new HashMap<>();
        TableDataInfo<?> listData;
        BigDecimal totalAmount = BigDecimal.ZERO;

        // 启动分页

        switch (type) {
            case "store":
                // 店铺回款详情
                listData = queryList2(id, date);
                totalAmount = statisticsMapper.queryList2Total(id, date);
                break;
            case "person":
                // 个人回款详情
                listData = queryList5(id, date);
                totalAmount = statisticsMapper.queryList5Total(id, date);
                break;
            case "product_store":
                // 主产品单品各店回款详情
                listData = queryListProductRepayment(id, productId, date);
                totalAmount = statisticsMapper.queryListProductRepaymentTotal(id, productId, date);
                break;
            default:
                listData = TableDataInfo.build(Collections.emptyList());
                break;
        }

        result.put("list", listData);
        result.put("totalAmount", totalAmount);
        return result;
    }

    /**
     * 查询主产品单品在特定店铺的回款详情
     */
    public TableDataInfo<HmSaleOrderPickUpVo> queryListProductRepayment(Long id, Long productId, String date) {
        List<HmSaleOrderPickUpVo> list = statisticsMapper.queryListProductRepayment(id, productId, date,20);
        return TableDataInfo.build(list);
    }


    @Override
    public RefundAndReturnStatsResultVo queryRefundAndReturnStats(String storeId, String date, String dateMode,PageQuery pageQuery,String salespersonId) {
        // 1. 获取图表统计数据
        List<Map<String, Object>> statsData = statisticsMapper.queryRefundStats(dateMode, date, storeId);

        // 2. 将Map列表转换为RefundStatsVo对象
        RefundStatsVo chartData = new RefundStatsVo();
        // 初始化所有月份/周的默认数据为0，以确保图表完整性
        List<String> labels;
        if ("year".equals(dateMode)) {
            labels = Arrays.asList("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12");
        } else {
            labels = Arrays.asList("第1周", "第2周", "第3周", "第4周");
        }
        List<BigDecimal> refundAmountList = new ArrayList<>(Collections.nCopies(labels.size(), BigDecimal.ZERO));
        List<Integer> returnedPickedCPList = new ArrayList<>(Collections.nCopies(labels.size(), 0));
        List<Integer> returnedPickedZPList = new ArrayList<>(Collections.nCopies(labels.size(), 0));

        // 填充实际数据
        for (Map<String, Object> map : statsData) {
            String label = (String) map.get("label");
            int index = -1;
            if ("year".equals(dateMode)) {
                try {
                    index = Integer.parseInt(label) - 1; // "01" -> 0, "02" -> 1
                } catch (NumberFormatException e) {
                }
            } else { // month mode, "第X周"
                if (label.startsWith("第") && label.endsWith("周")) {
                    try {
                        index = Integer.parseInt(label.substring(1, label.length() - 1)) - 1;
                        if (index >= labels.size()) index = -1; // Prevent out of bounds if weeks exceed 4
                    } catch (NumberFormatException e) {
                    }
                }
            }

            if (index != -1 && index < labels.size()) {
                refundAmountList.set(index, (BigDecimal) map.get("refundAmount"));
                returnedPickedCPList.set(index, Convert.toInt(map.get("returnedPickedCP")));
                returnedPickedZPList.set(index, Convert.toInt(map.get("returnedPickedZP")));
            }
        }

        chartData.setLabels(labels);
        chartData.setRefundAmount(refundAmountList);
        chartData.setReturnedPickedCP(returnedPickedCPList);
        chartData.setReturnedPickedZP(returnedPickedZPList);

        // 4. 查询按销售人员统计的退款退货数据 (仅当 storeId 不为 'all' 时)
        if (StringUtils.isNotBlank(storeId) && !"all".equals(storeId)) {
            List<SalespersonRefundStatsVo> salespersonStats = statisticsMapper.queryRefundStatsBySalesperson(date, storeId);
            chartData.setSalespersonStats(salespersonStats);
        } else {
            chartData.setSalespersonStats(Collections.emptyList()); // 如果是全部店铺，则不按人员统计
        }

        // 3. 获取明细数据 (这里分页参数是固定的)
        HmSaleOrderRefundBo bo = new HmSaleOrderRefundBo();
        if (StringUtils.isNotBlank(storeId) && !"all".equals(storeId)) {
            bo.setStoreId(storeId);
        }
        // 设置时间范围过滤
        if ("year".equals(dateMode)) {
            bo.getParams().put("beginTime", date + "-01-01 00:00:00");
            bo.getParams().put("endTime", date + "-12-31 23:59:59");
        } else { // month mode
            bo.getParams().put("beginTime", date + "-01 00:00:00");
            // 获取当月最后一天
            LocalDate lastDayOfMonth = LocalDate.parse(date + "-01").plusMonths(1).minusDays(1);
            bo.getParams().put("endTime", lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 23:59:59");
        }

        // **设置销售人员过滤**
        if (salespersonId != null) {
            bo.setSalespersonId(Convert.toLong(salespersonId));
        }

        IPage<HmSaleOrderRefundVo> page = statisticsMapper.queryRefundDetails(pageQuery.build(), bo);

        // 4. 封装结果对象
        RefundAndReturnStatsResultVo result = new RefundAndReturnStatsResultVo();
        result.setChartData(chartData);
        result.setDetailsData(TableDataInfo.build(page));

        return result;
    }

}
